package com.longtxt.core.ble.main

import android.Manifest
import android.annotation.SuppressLint
import android.app.ForegroundServiceStartNotAllowedException
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
import android.os.Binder
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import com.longtxt.core.ble.BleManager
import timber.log.Timber

class BleService : Service() {
    private val binder = LocalBinder()
    private var blePeripheral: BlePeripheral? = null
    private var _mErrorCallback: BleCommonErrorCallback? = null

    val bleDevice get() = blePeripheral

    private var needForeService = false

    fun setNeedForeService(needForeService: Boolean) {
        this.needForeService = needForeService
    }

    fun cancelBondProcess(){
        blePeripheral?.cancelBondProcess()
    }

    @SuppressLint("MissingPermission")
    fun connectToDevice(
        needBond: Boolean,
        device: BluetoothDevice,
        callback: BlePeripheralCallback,
        errorCallback: BleCommonErrorCallback
    ): Boolean {
        blePeripheral = null
        blePeripheral = BlePeripheral(this, device, callback) {
            errorCallback.onTimeout()
        }
        _mErrorCallback = errorCallback
        return blePeripheral!!.createBond(needBond)
    }

    fun writeCommandData(data: ByteArray): Boolean? {
        return blePeripheral?.writeJsonRequest(data)
    }

    fun writeJlData(data: ByteArray): Boolean? {
        return blePeripheral?.writeJLRequest(data)
    }

    fun reconnect(): Boolean {
        if (blePeripheral == null) {
            return false
        }
        return blePeripheral!!.createBond(false)
    }

    fun clearBleCache() {
        blePeripheral?.clearServicesCache()
    }

    fun disconnect() {
        _mErrorCallback = null
        blePeripheral?.disconnect()
    }

    override fun onBind(intent: Intent?): IBinder {
        return binder
    }

    override fun onUnbind(intent: Intent?): Boolean {
        blePeripheral?.disconnect()
        blePeripheral = null
        return super.onUnbind(intent)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Read the needForeService flag from intent
        intent?.let {
            needForeService = it.getBooleanExtra("needForeService", false)
        }
        
        Timber.i("BleService.onStartCommand: invoked, needForeService: $needForeService")
        if (!hasRequiredPermissions()) {
            Timber.w("BleService.onStartCommand: missing permissions, stopping service")
            stopSelf()
            return START_NOT_STICKY
        }
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && needForeService) {
            try {
                Timber.i("BleService.onStartCommand: calling startForegroundServiceProperly")
                startForegroundServiceProperly()
                START_STICKY
            } catch (e: IllegalStateException) {
                Timber.e(e, "BleService.onStartCommand: IllegalStateException starting foreground")
                stopSelf()
                START_NOT_STICKY
            }
        } else {
            Timber.i("BleService.onStartCommand: running as background service")
            START_STICKY
        }
    }

    private fun startForegroundServiceProperly(){
        Timber.i("BleService.startForegroundServiceProperly: starting foreground")
        BleManager.notification.let {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                startForeground(1, it, FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE)
            } else {
                startForeground(1, it)
            }
        }
    }

    private fun hasRequiredPermissions(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.BLUETOOTH_CONNECT
            ) == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(
                        this,
                        Manifest.permission.BLUETOOTH_SCAN
                    ) == PackageManager.PERMISSION_GRANTED
        } else {
            true // For older versions, permissions are granted by default
        }
    }

    inner class LocalBinder : Binder() {
        fun getService(): BleService {
            return this@BleService
        }
    }

    companion object {

    }
}